package com.easylinkin.linkappapi.keywork.utils;

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.apache.xmlbeans.XmlObject;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

public class WordTableExportUtil {

    /**
     * 导出Word表格到浏览器
     * @param response HttpServletResponse对象
     * @param fileName 导出文件名（不带后缀）
     * @param headerRows 固定表头行数据（每行一个Map，key为列索引，value为内容）
     * @param dataRows 动态数据行（每行一个Map，key为列索引，value为内容）
     * @param footerRows 固定表尾行数据
     * @param mergeRegions 合并区域列表，格式为 [起始行, 结束行, 起始列, 结束列]
     * @throws IOException
     */
    public static void exportWordTable(HttpServletResponse response, String fileName,
                              List<Map<Integer, String>> headerRows,
                              List<Map<Integer, String>> dataRows,
                              List<Map<Integer, String>> footerRows,
                              List<int[]> mergeRegions) throws IOException {

        // 1. 设置响应头
        setResponseHeaders(response, fileName);

        // 2. 创建Word文档
        try (XWPFDocument document = new XWPFDocument();
             OutputStream out = response.getOutputStream()) {

            // 3. 创建表格（不自动生成行）
            CTTbl ctTbl = document.getDocument().getBody().addNewTbl();
            XWPFTable table = new XWPFTable(ctTbl, document);

            // 4. 设置表格基本样式
            setBasicTableStyle(table);

            // 5. 添加固定表头行（直接从第一行开始）
            addRowsToTable(table, headerRows, true);

            // 6. 添加动态数据行
            addRowsToTable(table, dataRows, false);

            // 7. 添加固定表尾行
            addRowsToTable(table, footerRows, false);

            // 8. 处理合并单元格
            handleMergedRegions(table, mergeRegions);

            // 9. 写入输出流
            document.write(out);
        }
    }

    /**
     * 设置响应头（处理中文文件名）
     */
    private static void setResponseHeaders(HttpServletResponse response, String fileName) throws IOException {
        response.setContentType("application/octet-stream");
        String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName + ".docx");
    }

    /**
     * 设置表格基本样式
     */
    private static void setBasicTableStyle(XWPFTable table) {
        // 设置表格宽度
        CTTblWidth width = table.getCTTbl().addNewTblPr().addNewTblW();
        width.setType(STTblWidth.DXA);
        width.setW(BigInteger.valueOf(9000));

        // 设置表格边框
        table.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
        table.setInsideVBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
        table.setLeftBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
        table.setRightBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
        table.setTopBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
        table.setBottomBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
    }

    /**
     * 添加行到表格
     */
    private static void addRowsToTable(XWPFTable table, List<Map<Integer, String>> rows, boolean isHeader) {
        if (rows == null || rows.isEmpty()) return;

        for (Map<Integer, String> rowData : rows) {
            XWPFTableRow row = table.createRow();
            row.setHeight(400); // 设置行高

            for (Map.Entry<Integer, String> entry : rowData.entrySet()) {
                int colIndex = entry.getKey();
                String value = entry.getValue();

                // 确保单元格存在
                while (colIndex >= row.getTableCells().size()) {
                    row.addNewTableCell();
                }

                XWPFTableCell cell = row.getCell(colIndex);
                cell.setText(value);
                setCellStyle(cell, isHeader);
            }
        }
    }

    /**
     * 设置单元格样式（POI 4.1.0版本）
     */
    private static void setCellStyle(XWPFTableCell cell, boolean isHeader) {
        // 设置垂直居中
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);

        // 设置水平居中
        CTTc cttc = cell.getCTTc();
        CTTcPr ctPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();

        // POI 4.1.0特有方式设置居中
//        if (!ctPr.isSetJc()) {
//            ctPr.addNewJc();
//        }
//        ctPr.getJc().setVal(JcEnumeration.CENTER);

        // 设置表头样式
        if (isHeader) {
            CTShd ctshd = ctPr.isSetShd() ? ctPr.getShd() : ctPr.addNewShd();
            ctshd.setFill("D3D3D3"); // 灰色背景

            // 设置表头字体加粗
//            CTPPr ppr = cttc.addNewP().addNewPPr();
//            CTRPr rpr = ppr.addNewRPr();
//            rpr.addNewB().setVal(STOnOff.TRUE);
        }
    }

    /**
     * 处理合并单元格
     */
    private static void handleMergedRegions(XWPFTable table, List<int[]> mergeRegions) {
        if (mergeRegions == null || mergeRegions.isEmpty()) return;

        for (int[] region : mergeRegions) {
            if (region.length == 4) {
                int startRow = region[0];
                int endRow = region[1];
                int startCol = region[2];
                int endCol = region[3];

                // 检查行和列是否有效
                if (startRow >= 0 && endRow < table.getNumberOfRows() &&
                        startCol >= 0 && endCol < table.getRow(0).getTableCells().size()) {

                    // Apache POI合并单元格的方法
                    mergeCells(table, startRow, endRow, startCol, endCol);
                }
            }
        }
    }

    /**
     * 实际合并单元格的方法
     */
    private static void mergeCells(XWPFTable table, int startRow, int endRow, int startCol, int endCol) {
        for (int rowIndex = startRow; rowIndex <= endRow; rowIndex++) {
            XWPFTableRow row = table.getRow(rowIndex);
            for (int colIndex = startCol; colIndex <= endCol; colIndex++) {
                XWPFTableCell cell = row.getCell(colIndex);
                if (cell != null) {
                    CTTcPr tcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();

                    // 如果是合并的起始单元格
                    if (rowIndex == startRow && colIndex == startCol) {
                        // 设置跨行跨列
                        if (endRow > startRow) {
                            tcPr.addNewVMerge().setVal(STMerge.RESTART);
                        }
                        if (endCol > startCol) {
                            tcPr.addNewHMerge().setVal(STMerge.RESTART);
                        }
                    } else {
                        // 其他单元格设置为继续合并
                        if (endRow > startRow) {
                            tcPr.addNewVMerge().setVal(STMerge.CONTINUE);
                        }
                        if (endCol > startCol) {
                            tcPr.addNewHMerge().setVal(STMerge.CONTINUE);
                        }
                    }
                }
            }
        }
    }
}